package com.wayhome.srpingbootmybatis.boc.util;


import com.alibaba.fastjson.JSONObject;
import org.springframework.util.Base64Utils;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 农行  接口参数加解密
 */
public class AbcChannelSHA256WithRSAUtil {

    /**
     * 将json 先按字典排序，然后格式化成 key1=value1&key2=value2...
     * @param json
     * @return 排序后的结果
     */
    public static String sortAndFormat (JSONObject json) {
        List<String> keyList = new ArrayList<>(json.keySet());
        Collections.sort(keyList);
        StringBuilder sb = new StringBuilder ();
        for (String key : keyList) {
            String value = json.getString (key);
            if (value==null || value.length ()==0) {
                continue;
            }
            if (sb.length () > 0) {
                sb.append ("&");
            }
            sb.append(key).append ("=").append (value);
        }
        return sb.toString ();
    }

    /**
     * 用私钥对信息生成数字签名
     * @param data 加密数据
     * @param privateKey 私钥
     */
    public static String sign(byte[] data, String privateKey) throws Exception {
        byte [] keyBytes = Base64Utils.decode(privateKey.getBytes());
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec (keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance ("RSA");
        PrivateKey privateK = keyFactory.generatePrivate (pkcs8KeySpec);
        Signature signature = Signature.getInstance ("SHA256WithRSA");
        signature.initSign (privateK);
        signature.update (data);
        return new String(Base64Utils.encode(signature.sign()));
    }

    /**
     * 校验数字签名
     * @param data 加密数据
     * @param publicKey 公钥
     * @param sign 数字签名
     */
    public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
        byte [] keyBytes = Base64Utils.decode(publicKey.getBytes());
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec (keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance ("RSA");
        PublicKey publicK = keyFactory.generatePublic (keySpec);
        Signature signature = Signature.getInstance ("SHA256WithRSA");
        signature.initVerify(publicK);
        signature.update (data);
        return signature.verify (Base64Utils.decode(sign.getBytes()));
    }
}
